﻿#define SHOW
using System.Drawing;
using System.Windows.Forms;
using Sharp3DMath.Strokes;
using Sharp3DMath.Core;
using Sharp3DMath.Geometry2D;
using System.Collections.Generic;
using AI.Fuzzy.Library;
using System;

namespace SketchRecognise
{   //Todo features的计算 有问题 需要调用StrokeFeatureBase类
    //Todo GlobalFeaturesPanel的使用
    //Todo 
   

    

    public partial class SketchPaintControl : UserControl
    {
        private List<Stroke> strokes;
        private List<CustomStroke> beautyStrokes;
        

        public class SketchDrawingFinishedEventArgs : EventArgs
        {
            public readonly GlobalGeometricFeature Features;
            public SketchDrawingFinishedEventArgs(GlobalGeometricFeature features)
            {
                Features = features;
            }
        }

        public class SketchRecogniseFinishedEventArgs : EventArgs
        {
            public readonly List<RuleResult> RecogniseResults;
            public readonly GlobalGeometricFeatureGenerator Features;
            public SketchRecogniseFinishedEventArgs(List<RuleResult> results, GlobalGeometricFeatureGenerator features)
            {
                RecogniseResults = results;
                Features = features;
            }
        }

        public delegate void SketchDrawingFinishedEventHandler(object sender, SketchDrawingFinishedEventArgs e);
        public delegate void SketchRecogniseFinishedEventHandler(object sender,SketchRecogniseFinishedEventArgs e);

        public event SketchDrawingFinishedEventHandler SketchDrawingFinished;
        public event SketchRecogniseFinishedEventHandler SketchRecogniseFinished;
        public SketchPaintControl()
        {
            InitializeComponent();
            SRFLS = new SRFuzzyLogicSystem();
#if SHOW
            strokes = new List<Stroke>();
            beautyStrokes = new List<CustomStroke>();
#else
            strokes = null;
            beautyStrokes = null;
#endif


        }
        //Todo SRFuzzyLogicSystem interface
        public SketchPaintControl(SRFuzzyLogicSystem srfls)
        {
            InitializeComponent();
            SRFLS = srfls;
        }
        #region Private Attribute
        private Stroke stroke = Stroke.Zero;

        private bool isShowCH = false;//convex hull
        private bool isShowLQ = false;//Largest Q
        private bool isShowER = false;//Enclosing Rectangle
        private bool isShowLT = false;//Largest Triangle
        

        private bool isShowChVertex = false;
        private bool isShowLQVertex = false;
        private bool isShowERVertex = false;
        private bool isShowLTVertex = false;

        private bool isShowBeautySharp = false;
        private bool isShowOriginalSharp = true;

        private bool isCalculateGeometricFigures = false;

        SRFuzzyLogicSystem SRFLS = null;
        MamdaniFuzzySystem _srfls = null;
        

        
        Pen strokePen = new Pen(Color.BlueViolet, 2);
        Pen beautyPen = new Pen(Color.Black, 3);

       
        Pen chPen = new Pen(Color.Red, 1);

        
        Pen erPen = new Pen(Color.DarkOrange, 1);

        
        Pen ltPen = new Pen(Color.RoyalBlue, 1.5f);

       
        Pen lqPen = new Pen(Color.SeaGreen, 1.5f);

        
        #endregion
         
        #region Public Attribute
        public Stroke PaintStroke
        {
            set 
            { 
                stroke = value;
                if (IsCalculateGeometricFigures)
                {
                    featuresGenerator.Clear();globalFeatures = featuresGenerator.LoadFrom(stroke);
                }
            }
            get { return stroke; }
        }
    
        public bool IsCalculateGeometricFigures
        {
            get 
            {
                return IsShowCH || IsShowER||IsShowLQ||IsShowLT||isCalculateGeometricFigures;
            }
            set
            {
                isCalculateGeometricFigures = value;
            }
        }
        public bool IsShowLQ
        {
            get { return isShowLQ; }
            set { isShowLQ = value; }
        }
        public bool IsShowLT
        {
            get { return isShowLT; }
            set { isShowLT = value; }
        }
        public bool IsShowER
        {
            get { return isShowER; }
            set { isShowER = value; }
        }
        public bool IsShowCH
        {
            get { return isShowCH; }
            set { isShowCH = value; }
        }

        public bool IsShowBeautySharp
        {
            get { return isShowBeautySharp; }
            set { isShowBeautySharp = value; }
        }
        public bool IsShowOriginalSharp
        {
            get { return isShowOriginalSharp; }
            set { isShowOriginalSharp = value; }
        }

        public bool IsShowCHVertex
        {
            get { return isShowChVertex; }
            set { isShowChVertex = value; }
        }
        public bool IsShowLQVertex
        {
            get { return isShowLQVertex; }
            set { isShowLQVertex = value; }
        }
        public bool IsShowERVertex
        {
            get { return isShowERVertex; }
            set { isShowERVertex = value; }
        }
        public bool IsShowLTVertex
        {
            get { return isShowLTVertex; }
            set { isShowLTVertex = value; }
        }

        public Pen StrokePen
        {
            get { return strokePen; }
            set { strokePen = value; }
        }
        public Pen ChPen
        {
            get { return chPen; }
            set { chPen = value; }
        }
        public Pen ErPen
        {
            get { return erPen; }
            set { erPen = value; }
        }
        public Pen LtPen
        {
            get { return ltPen; }
            set { ltPen = value; }
        }
        public Pen LqPen
        {
            get { return lqPen; }
            set { lqPen = value; }
        }
        #endregion

        private Graphics DC;
        bool drawingTag = false;
        private Point lastPosition = Point.Empty;
        List<RuleResult> myResults = null;

        GlobalGeometricFeatureGenerator featuresGenerator = new GlobalGeometricFeatureGenerator();
        GlobalGeometricFeature globalFeatures = GlobalGeometricFeature.Zero;

        public GlobalGeometricFeature GlobalFeatures
        {
            get { return globalFeatures; }
        }

        private void SketchPaintControl_MouseDown(object sender, MouseEventArgs e)
        {
            Invalidate();
            drawingTag = true;
            if (!stroke.Empty)
            {
                //stroke.Clear();
                stroke = Stroke.Zero;
            }
            stroke.AddActivePoint(new Vector2F(e.X, e.Y));
            lastPosition.X = e.X;
            lastPosition.Y = e.Y;
            DC = CreateGraphics();
        }

        private void SketchPaintControl_MouseMove(object sender, MouseEventArgs e)
        {
            if (drawingTag)
            {
                if (e.X != lastPosition.X || e.Y != lastPosition.Y)
                {
                    stroke.AddActivePoint(new Vector2F(e.X, e.Y));

                    DC.DrawLine(strokePen, lastPosition, e.Location);
                    lastPosition.X = e.X;
                    lastPosition.Y = e.Y;
                }
            }
        }

        private void SketchPaintControl_MouseUp(object sender, MouseEventArgs e)
        {
            drawingTag = false;
            if (stroke.Points.Count<=20)
            {
                stroke.Clear();
                return;
            }
            strokes.Add(stroke);

            if (IsCalculateGeometricFigures)
            {

                globalFeatures = featuresGenerator.LoadFrom(stroke);
                if (SketchDrawingFinished!=null)
                {
                    SketchDrawingFinished(this,new SketchDrawingFinishedEventArgs(globalFeatures));
                }
                //Todo We need an event;
                #region Show Geometric Features Sharp
                if (IsShowCH)
                {
                    GraphicsEx.DrawPolygon(DC, ChPen, featuresGenerator.ChPoints);
                    if (IsShowCHVertex)
                    {
                        foreach (var item in featuresGenerator.ChPoints)
                        {
                            RectangleF rect = new RectangleF(item.X, item.Y, 0, 0);
                            rect.Inflate(3, 3);
                            DC.DrawRectangle(chPen, rect.X, rect.Y, rect.Width, rect.Height);
                        }
                    }
                }
                if (IsShowER)
                {
                    GraphicsEx.DrawPolygon(DC, ErPen, featuresGenerator.ErPoints);
                    if (IsShowERVertex)
                    {
                        foreach (var item in featuresGenerator.ErPoints)
                        {
                            RectangleF rect = new RectangleF(item.X, item.Y, 0, 0);
                            rect.Inflate(3, 3);
                            DC.DrawRectangle(erPen, rect.X, rect.Y, rect.Width, rect.Height);
                        }
                    }
                }
                if (IsShowLQ)
                {
                    GraphicsEx.DrawPolygon(DC, LqPen, featuresGenerator.LqPoints);
                    if (IsShowLQVertex)
                    {
                        foreach (var item in featuresGenerator.LqPoints)
                        {
                            RectangleF rect = new RectangleF(item.X, item.Y, 0, 0);
                            rect.Inflate(3, 3);
                            DC.DrawRectangle(lqPen, rect.X, rect.Y, rect.Width, rect.Height);
                        }
                    }
                }
                if (IsShowLT)
                {
                    GraphicsEx.DrawPolygon(DC, LtPen, featuresGenerator.LtPoints);
                    if (IsShowLTVertex)
                    {
                        foreach (var item in featuresGenerator.LtPoints)
                        {
                            RectangleF rect = new RectangleF(item.X, item.Y, 0, 0);
                            rect.Inflate(3, 3);
                            DC.DrawRectangle(ltPen, rect.X, rect.Y, rect.Width, rect.Height);
                        }
                    }
                }

                #endregion Show Geometric Features Sharp
                //Todo FuzzyLogic Server 
                #region Fuzzy Logic Test
                if (SRFLS!=null)
                {
                    StrokeFeaturesBase featureBase = new StrokeFeaturesBase();
                    featureBase.ComputeFeatures(globalFeatures);

                    //
                    // Get variables from the system (for convinience only)
                    //
                    FuzzyVariable srHer_Wer = _srfls.InputByName("Her_Wer");
                    FuzzyVariable srPch2_Ach4PI = _srfls.InputByName("Pch2_Ach4PI");
                    FuzzyVariable srAlt_Ach = _srfls.InputByName("Alt_Ach");
                    FuzzyVariable srAlt_Alq = _srfls.InputByName("Alt_Alq");
                    FuzzyVariable srAch_Aer = _srfls.InputByName("Ach_Aer");
                    FuzzyVariable srAlq_Aer = _srfls.InputByName("Alq_Aer");
                    FuzzyVariable srHollowness = _srfls.InputByName("Hollowness");
                    FuzzyVariable srTl_Pch = _srfls.InputByName("Tl_Pch");
                    FuzzyVariable srAlq_Ach = _srfls.InputByName("Alq_Ach");
                    FuzzyVariable srAlt_Aer = _srfls.InputByName("Alt_Aer");
                    FuzzyVariable srPlq_Pch = _srfls.InputByName("Plq_Pch");


                    FuzzyVariable srSharp = _srfls.OutputByName("Sharp");
                    //
                    // Associate input values with input variables
                    //
                    Dictionary<FuzzyVariable, double> inputValues = new Dictionary<FuzzyVariable, double>();
                    inputValues.Add(srHer_Wer, featureBase.Her_Wer);
                    inputValues.Add(srPch2_Ach4PI, featureBase.Pch2_Ach4PI);
                    inputValues.Add(srAlt_Ach, featureBase.Alt_Ach);
                    inputValues.Add(srAlt_Alq, featureBase.Alt_Alq);
                    inputValues.Add(srAch_Aer, featureBase.Ach_Aer);
                    inputValues.Add(srAlq_Aer, featureBase.Alq_Aer);
                    inputValues.Add(srHollowness, featureBase.Hollowness);
                    inputValues.Add(srTl_Pch,featureBase.Tl_Pch);
                    inputValues.Add(srAlq_Ach,featureBase.Alq_Ach);
                    inputValues.Add(srAlt_Aer, featureBase.Alt_Aer);
                    inputValues.Add(srPlq_Pch, featureBase.Plq_Pch);

                    //Todo SharpResult 与 MyResult之间的转换
                    myResults = _srfls.LRSSCalculate(inputValues);
                    
                    if (SketchRecogniseFinished!=null)
                    {
                        SketchRecogniseFinished(this, new SketchRecogniseFinishedEventArgs(myResults, featuresGenerator));
                    }

                   

                }



                #endregion Fuzzy Logic Test

              


                #region Beatuifition the Sharp
                if (myResults!=null)
                {
                    LRSS_SharpResult results = new LRSS_SharpResult();
                    foreach (var item in myResults)
                    {
                        results.Add(new Sharp(item.FuzzyTermName, item.Value));
                    }
                    results.Sort();
                    
                    switch (results[0].sharpName)
                    {
                        case "Line":
                            {
                                double k =0,b =0;
                                bool re = MathEx.FitToLine(stroke.Points.ToArray(), ref k, ref b);
                                if (re==false)
                                {
                                    Console.WriteLine("false");

                                    break;
                                }
                                double y1 = 0, y2 = 0;
                                y1 = k * stroke.Points[0].X + b;
                                y2 = k * stroke.Points[stroke.Points.Count - 1].X + b;
                                PointF p1 = new PointF(stroke.Points[0].X, (float)y1);
                                PointF p2 = new PointF(stroke.Points[stroke.Points.Count - 1].X, (float)y2);
                                if (beautyStrokes != null)
                                {
                                    CustomStroke bStroke = new CustomStroke(SharpType.Line);
                                    bStroke.AddPoint(new Vector2F(p1));
                                    bStroke.AddPoint(new Vector2F(p2));
                                    beautyStrokes.Add(bStroke);
                                }
                                
                                Graphics graphics = CreateGraphics();
                                graphics.DrawLine(beautyPen, p1, p2);
                                graphics.Dispose();

                               

                                myResults = null;
                                break;
                            }
                        case "Triangle":
                            {
                                if (beautyStrokes != null)
                                {
                                    CustomStroke bStroke = new CustomStroke(SharpType.Triangle);
                                    foreach (var item in featuresGenerator.LtPoints)
                                    {
                                        bStroke.AddPoint(item);
                                    }
                                    beautyStrokes.Add(bStroke);
                                }
                                Graphics graphics = CreateGraphics();
                                GraphicsEx.DrawPolygon(graphics, beautyPen, featuresGenerator.LtPoints);
                                graphics.Dispose();
                                myResults = null;
                                break;
                            }
                        case "Trapezia":
                            {
                                if (beautyStrokes != null)
                                {
                                    CustomStroke bStroke = new CustomStroke(SharpType.Trapezia);
                                    foreach (var item in featuresGenerator.LqPoints)
                                    {
                                        bStroke.AddPoint(item);
                                    }
                                    beautyStrokes.Add(bStroke);
                                }
                                Graphics graphics = CreateGraphics();
                                GraphicsEx.DrawPolygon(graphics, beautyPen, featuresGenerator.LqPoints);
                                graphics.Dispose();
                                myResults = null;
                                break;
                            }
                        case "Diamond":
                            {
                                if (beautyStrokes != null)
                                {
                                    CustomStroke bStroke = new CustomStroke(SharpType.Diamond);
                                    foreach (var item in featuresGenerator.LqPoints)
                                    {
                                        bStroke.AddPoint(item);
                                    }
                                    beautyStrokes.Add(bStroke);
                                }
                                Graphics graphics = CreateGraphics();
                                GraphicsEx.DrawPolygon(graphics, beautyPen, featuresGenerator.LqPoints);
                                graphics.Dispose();
                                myResults = null;
                                break;
                            }
                       
                        case "Rectangle":
                            {
                                if (beautyStrokes != null)
                                {
                                    CustomStroke bStroke = new CustomStroke(SharpType.Rectangle);
                                    foreach (var item in featuresGenerator.ErPoints)
                                    {
                                        bStroke.AddPoint(item);
                                    }
                                    beautyStrokes.Add(bStroke);
                                }
                                Graphics graphics = CreateGraphics();
                                GraphicsEx.DrawPolygon(graphics, beautyPen, featuresGenerator.ErPoints);
                                graphics.Dispose();
                                myResults = null;
                                break;
                            }
                        case "Ellipse":
                            {
                                if (beautyStrokes != null)
                                {
                                    CustomStroke bStroke = new CustomStroke(SharpType.Ellipse);
                                    foreach (var item in featuresGenerator.ErPoints)
                                    {
                                        bStroke.AddPoint(item);
                                    }
                                    beautyStrokes.Add(bStroke);
                                }
                                Graphics graphics = CreateGraphics();
                                GraphicsEx.DrawRotateEllipse(graphics, beautyPen, featuresGenerator.ErPoints);
                                graphics.Dispose();
                                myResults = null;
                                break;
                            }
                        case "Circles":
                            {
                                if (beautyStrokes != null)
                                {
                                    CustomStroke bStroke = new CustomStroke(SharpType.Ellipse);
                                    foreach (var item in featuresGenerator.ErPoints)
                                    {
                                        bStroke.AddPoint(item);
                                    }
                                    beautyStrokes.Add(bStroke);
                                }
                                Graphics graphics = CreateGraphics();
                                GraphicsEx.DrawRotateEllipse(graphics, beautyPen, featuresGenerator.ErPoints);
                                graphics.Dispose();
                                myResults = null;
                                break;
                            }
                        case "Arc":
                            {
                                Graphics graphics = CreateGraphics();
                                int[] indices = null;
                                Vector2F[] pts = StrokeAnalyzer.SegmentizeStroke(stroke, 5, out indices);
                                //Vector2F[] pts = stroke.Points.ToArray();
                                pts = StrokeAnalyzer.RemoveNearPoints(pts, stroke.StrokeLength*0.03);
                                if (pts.Length>7)
                                {
                                    GraphicsEx.DrawVertexs(graphics, ChPen, pts);

                                }
                                else
                                {
                                    pts = StrokeAnalyzer.StrokeApprox(stroke.Points.ToArray(), MathEx.Round(stroke.Points.Count * 0.1));
                                    GraphicsEx.DrawVertexs(graphics, ErPen, pts);
                                }

                                


                                pts = MathEx.EllipsePaint(graphics, pts, FitMode.FPF,100);

                                pts = MathEx.Point2DSort_Clockwise(pts);

                                int sindex = 0, eindex = 0;
                                DistanceMethods.Distance(pts, stroke.Points[0], ref sindex);
                                DistanceMethods.Distance(pts, stroke.Points[stroke.Points.Count - 1], ref eindex);

                                int minIndex = Math.Min(sindex, eindex);
                                int maxIndex = Math.Max(sindex, eindex);

                                int order = StrokeAnalyzer.OrderDetected(stroke.Points[0], stroke.Points[stroke.Points.Count / 2], stroke.Points[stroke.Points.Count-1]);
                                int fitorder = StrokeAnalyzer.OrderDetected(pts[0], pts[pts.Length / 2], pts[pts.Length - 1]);
                               
                               
                                if (order == -1)
                                {
                                    //if (beautyStrokes != null)
                                    //{
                                    //    Console.WriteLine("tag -1");
                                    //    CustomStroke bStroke = new CustomStroke(SharpType.Arc);
                                    //    Vector2F[] pts1 = new Vector2F[minIndex+1];
                                    //    Vector2F[] pts2 = new Vector2F[pts.Length - maxIndex];
                                    //    for (int i = 0; i <=minIndex; i++)
                                    //    {
                                    //        pts1[i] = new Vector2F(pts[i]);
                                         
                                    //       //   bStroke.AddPoint(new Vector2F(pts[i]));
                                    //    }
                                      
                                    //    for (int i = maxIndex; i <= pts.Length-1; i++)
                                    //    {
                                    //        pts2[i-maxIndex] = new Vector2F(pts[i]);
                                    //        //bStroke.AddPoint(new Vector2F(pts[i]));
                                    //    }
                                       
                                    //    foreach (var item in pts1)
                                    //    {
                                    //        bStroke.AddPoint(item);
                                    //    }
                                    //    foreach (var item in pts2)
                                    //    {
                                    //        bStroke.AddPoint(item);
                                    //    }
                                    //    bStroke.Points = new List<Vector2F>(MathEx.Point2DSort_AntiClockwise(bStroke.Points.ToArray()));
                                    //    beautyStrokes.Add(bStroke);
                                    //}
                                    //GraphicsEx.DrawLines(graphics, beautyPen, pts, 0, minIndex);
                                    //GraphicsEx.DrawLines(graphics, beautyPen, pts, maxIndex, pts.Length - 1);

                                    if (sindex < eindex)
                                    {
                                        if (beautyStrokes != null)
                                        {
                                            Console.WriteLine("tag 1.1");
                                            CustomStroke bStroke = new CustomStroke(SharpType.Arc);
                                            Vector2F[] pts1 = new Vector2F[sindex + 1];
                                            Vector2F[] pts2 = new Vector2F[pts.Length - eindex];
                                            for (int i = 0; i <= sindex; i++)
                                            {
                                                pts1[i] = new Vector2F(pts[i]);

                                                //   bStroke.AddPoint(new Vector2F(pts[i]));
                                            }
                                            //  pts1 = MathEx.Point2DSort_Clockwise(pts1);
                                            for (int i = eindex; i <= pts.Length - 1; i++)
                                            {
                                                pts2[i - eindex] = new Vector2F(pts[i]);
                                                //bStroke.AddPoint(new Vector2F(pts[i]));
                                            }
                                            // pts2 = MathEx.Point2DSort_Clockwise(pts2);
                                            foreach (var item in pts1)
                                            {
                                                bStroke.AddPoint(item);
                                            }
                                            foreach (var item in pts2)
                                            {
                                                bStroke.AddPoint(item);
                                            }
                                            bStroke.Points = new List<Vector2F>(MathEx.Point2DSort_AntiClockwise(bStroke.Points.ToArray()));
                                            bStroke.Points.Reverse();
                                            bStroke.Points.RemoveAt(bStroke.Points.Count - 1);
                                            beautyStrokes.Add(bStroke);
                                        }

                                        GraphicsEx.DrawLines(graphics, beautyPen, pts, 0, sindex);
                                        GraphicsEx.DrawLines(graphics, beautyPen, pts, eindex, pts.Length - 1);
                                    }
                                    else
                                    {
                                        
                                        if (beautyStrokes != null)
                                        {
                                            Console.WriteLine("tag 1.2");
                                            CustomStroke bStroke = new CustomStroke(SharpType.Arc);

                                            for (int i = minIndex; i <= maxIndex; i++)
                                            {
                                                bStroke.AddPoint(new Vector2F(pts[i]));
                                            }
                                            //bStroke.Points = new List<Vector2F>(MathEx.Point2DSort_Clockwise(bStroke.Points.ToArray()));
                                            beautyStrokes.Add(bStroke);
                                        }
                                        GraphicsEx.DrawLines(graphics, beautyPen, pts, minIndex, maxIndex);
                                    }
                                }
                                else if (order == 1)
                                {
                                    if (sindex >= eindex)
                                    {
                                        if (beautyStrokes != null)
                                        {
                                            Console.WriteLine("tag 2.1");
                                            CustomStroke bStroke = new CustomStroke(SharpType.Arc);
                                            Vector2F[] pts1 = new Vector2F[eindex+1];
                                            Vector2F[] pts2 = new Vector2F[pts.Length - sindex];
                                            for (int i = 0; i <= eindex; i++)
                                            {
                                                pts1[i] = new Vector2F(pts[i]);

                                                //   bStroke.AddPoint(new Vector2F(pts[i]));
                                            }
                                          //  pts1 = MathEx.Point2DSort_Clockwise(pts1);
                                            for (int i = sindex; i <= pts.Length - 1; i++)
                                            {
                                                pts2[i-sindex] = new Vector2F(pts[i]);
                                                //bStroke.AddPoint(new Vector2F(pts[i]));
                                            }
                                           // pts2 = MathEx.Point2DSort_Clockwise(pts2);
                                            foreach (var item in pts1)
                                            {
                                                bStroke.AddPoint(item);
                                            }
                                            foreach (var item in pts2)
                                            {
                                                bStroke.AddPoint(item);
                                            }
                                            bStroke.Points = new List<Vector2F>(MathEx.Point2DSort_AntiClockwise(bStroke.Points.ToArray()));
                                            bStroke.Points.Reverse();
                                            bStroke.Points.RemoveAt(bStroke.Points.Count - 1);
                                            beautyStrokes.Add(bStroke);
                                        }
                                       
                                        GraphicsEx.DrawLines(graphics, beautyPen, pts, 0, eindex);
                                        GraphicsEx.DrawLines(graphics, beautyPen, pts, sindex, pts.Length - 1);
                                    }
                                    else
                                    {
                                        if (beautyStrokes != null)
                                        {
                                            Console.WriteLine("tag 2.2");
                                            CustomStroke bStroke = new CustomStroke(SharpType.Arc);

                                            for (int i = minIndex; i < maxIndex; i++)
                                            {
                                                bStroke.AddPoint(new Vector2F(pts[i]));
                                            }
                                          //  bStroke.Points = new List<Vector2F>(MathEx.Point2DSort(bStroke.Points.ToArray()));
                                            beautyStrokes.Add(bStroke);
                                        }
                                        GraphicsEx.DrawLines(graphics, beautyPen, pts, minIndex, maxIndex);
                                    }
                                    
                                }

                               
                 
                                graphics.Dispose();
                                myResults = null;
                                break;
                            }
                        case "Spiral":
                            {
                                Graphics graphics = CreateGraphics();
                                //GraphicsEx.DrawBSpline(graphics, ChPen, MathEx.BezierSpline.GetBezierSplinePoints(StrokeAnalyzer.StrokeApprox(stroke.Points.ToArray())));

                                //myResults = null;
                                int[] indices = null;
                                Vector2F[] pts = StrokeAnalyzer.SegmentizeStroke(stroke, 5, out indices);
                                pts = StrokeAnalyzer.RemoveNearPoints(pts, 25);
                                GraphicsEx.DrawBSpline(graphics, beautyPen, MathEx.BezierSpline.GetBezierSplinePoints(pts));
                                GraphicsEx.DrawVertexs(graphics, ChPen, pts);

                                if (beautyStrokes != null)
                                {
                                    CustomStroke bStroke = new CustomStroke(SharpType.Spiral);

                                    foreach (var item in pts)
                                    {
                                        bStroke.AddPoint(new Vector2F(item));
                                    }
                                    beautyStrokes.Add(bStroke);
                                }
                                graphics.Dispose();
                                myResults = null;
                                break;
                            }
                        case "Curve":
                            {
                                Graphics graphics = CreateGraphics();
                                //GraphicsEx.DrawBSpline(graphics, ChPen, MathEx.BezierSpline.GetBezierSplinePoints(StrokeAnalyzer.StrokeApprox(stroke.Points.ToArray())));
                                
                                //myResults = null;
                                int[] indices = null;
                                Vector2F[] pts = StrokeAnalyzer.SegmentizeStroke(stroke, 5, out indices);
                                pts = StrokeAnalyzer.RemoveNearPoints(pts, 25);
                                GraphicsEx.DrawBSpline(graphics, beautyPen, MathEx.BezierSpline.GetBezierSplinePoints(pts));
                                GraphicsEx.DrawVertexs(graphics, ChPen, pts);
                                graphics.Dispose();
                                if (beautyStrokes != null)
                                {
                                    CustomStroke bStroke = new CustomStroke(SharpType.Curve);

                                    foreach (var item in pts)
                                    {
                                        bStroke.AddPoint(new Vector2F(item));
                                    }
                                    beautyStrokes.Add(bStroke);
                                }
                                myResults = null;
                                break;
                            }
                        default:
                            break;
                    }
                    
                  
                }
               
                #endregion

            }

            DC.Dispose();
        }

        private void SketchPaintControl_Paint(object sender, PaintEventArgs e)
        {
            #region original
            if (strokes==null)
            {
                if (stroke == null)
                {
                    return;
                }
                if (!stroke.Empty)
                {

                    Graphics dc = e.Graphics;
                    GraphicsEx.DrawLines(dc, strokePen, stroke.Points);
                }

            }
            #endregion
            else
            {
                if (IsShowOriginalSharp)
                {
                    foreach (var item in strokes)
                    {
                        Graphics dc = e.Graphics;
                        GraphicsEx.DrawStroke(dc, strokePen, item);
                    }
                }
                if (IsShowBeautySharp)
                {
                    foreach (var item in beautyStrokes)
                    {
                        Graphics dc = e.Graphics;
                        GraphicsEx.DrawBeautyStroke(e.Graphics,beautyPen , item, item.Type);
                    }
                }
                
            }
           
        }

        private void SketchPaintControl_Clear()
        {
            stroke.Clear();
            Invalidate();
        }

        private void SketchPaintControl_Load(object sender, System.EventArgs e)
        {
            if (SRFLS!=null)
            {
                _srfls = SRFLS.CreateSystem();
            }

          //  IsShowLT = true;
            //IsShowLQ = true;
        }
        
    }
}
